﻿using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DeepZoomPivotConstructor.VisualLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RenderEngine;
using RenderEngineInterfaces;
using SimpleFileRendering;

namespace t_SimpleFileRendering
{


    /// <summary>
    ///This is a test class for TestStringWildCardToInfoRender and is intended
    ///to contain all TestStringWildCardToInfoRender Unit Tests
    ///</summary>
    [TestClass()]
    public class TestStringWildCardToInfoRender
    {
        [TestInitialize]
        public void InitForTest()
        {
            t_TestingLibrary.Utilities.MyClassInit();
        }

        [TestCleanup]
        public void ShutDownTest()
        {
            t_TestingLibrary.Utilities.MyClassDone();
        }

        [TestMethod()]
        public void TestRenderPriorityExistingFileNoDirSpecified()
        {
            var f = CreateFile("TestRenderPriorityExistingFileNoDirSpecified.txt");
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target, addLocalPath: false);

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(f.Name), "relative name should fail");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(f.FullName), "fully qualified name");
        }

        [TestMethod()]
        public void TestRenderPriorityExistingFileDirSpecified()
        {
            var f = CreateFile("TestRenderPriorityExistingFileDirSpecified.txt");
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target);

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(f.Name), "relative name should be ok");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(f.FullName), "fully qualified name");
        }

        [TestMethod()]
        public void TestRenderPriorityExistingNoLocalDirectory()
        {
            var d = CreateDirectory("TestRenderPriorityExistingDirectory.txt");
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target, addLocalPath: false);

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(d.Name), "relative name should fail");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(d.FullName), "fully qualified name");
        }

        [TestMethod]
        public void TestURL()
        {
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target);

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority("http://www.nytimes.com/junk.pdf"));
        }

        [TestMethod()]
        public void TestRenderPriorityExistingDirectory()
        {
            var d = CreateDirectory("TestRenderPriorityExistingDirectory");
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target);

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(d.Name), "relative name should fail");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, target.RenderPriority(d.FullName), "fully qualified name");
        }

        [TestMethod]
        public void TestRenderPriorityForWildcard()
        {
            var d = CreateDirectory("TestRenderPriorityForWildcard");
            CreateFile("f1.txt", d);
            CreateFile("f2.txt", d);
            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target);
            Assert.AreEqual(RenderPluginPriority.RPPGeneric, target.RenderPriority("TestRenderPriorityForWildcard\\*"), "wildcard should be ok");
        }

        [TestMethod]
        public void TestRenderWildCard()
        {
            var d = CreateDirectory("TestRenderWildCard");
            CreateFile("f1.txt", d);
            CreateFile("f2.txt", d);

            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target);

            var v = target.Render(string.Format(@"{0}\*.txt", d.Name)).Result;
            DummyRender.CheckCount(expFile: 2);
        }

        [TestMethod]
        public void TestRenderFileWeCantRender()
        {
            var d = CreateDirectory("TestRenderWildCard");
            CreateFile("f1.txt", d);
            CreateFile("f2.txt", d);

            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target, filedirmatcher: ".*pdf$");

            var v = target.Render(string.Format(@"{0}\*.txt", d.Name)).Result;
            DummyRender.CheckCount(expFile: 0);
        }

        [TestMethod]
        public void TestRenderFileWeFailToRender()
        {
            var d = CreateDirectory("TestRenderWildCard");
            CreateFile("f1.txt", d);
            CreateFile("f2.txt", d);

            StringWildCardToInfoRender target = new StringWildCardToInfoRender();
            PreparePlugin(target, postRenderMatch: ".*pdf$");

            var v = target.Render(string.Format(@"{0}\*.txt", d.Name)).Result;
            DummyRender.CheckCount(expFile: 2); // it gets called twice, though it will return null...
            Assert.AreEqual(0, v.SGNodeList.Count(), "# of images incorrect"); // which is why # of images is zero here!
        }

        private DirectoryInfo CreateDirectory(string p)
        {
            var d = new DirectoryInfo(p);
            if (d.Exists)
                d.Delete(true);
            d.Create();
            d.Refresh();
            return d;
        }

        /// <summary>
        /// To get out the individual variables.
        /// </summary>
        class testme
        {
            [Export("RelativePathBase")]
            public DirectoryInfo localLocation;
        }

        [Export(typeof(IRenderEngine))]
        class DummyRender : IRenderEngine
        {
            Regex fileDirMatcher;
            Regex postRenderMatch;
            public DummyRender(string renderWildcard = ".*", string postRenderMatch = ".*")
            {
                Count = 0;
                CountOther = 0;

                fileDirMatcher = new Regex(renderWildcard);
                this.postRenderMatch = new Regex(postRenderMatch);
            }

            public static void CheckCount(int expFile = 0)
            {
                Assert.AreEqual(expFile, Count, "# of file objects processed");
                Assert.AreEqual(0, CountOther, "# of other objects processed");
            }

            /// <summary>
            /// Get/Set how  many times this guy was called.
            /// </summary>
            public static int Count { get; set; }
            public static int CountOther { get; set; }

            public Task<Visual> RenderToFuture(object what, System.Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool requestComposableUnit = false)
            {
                bool willwork = false;
                if (what is string)
                {
                    if (!fileDirMatcher.Match((what as string)).Success)
                        return null;
                    willwork = postRenderMatch.Match((what as string)).Success;
                    Count++;
                }
                else
                {
                    CountOther++;
                }

                return Task<Visual>.Factory.StartNew(() =>
                {
                    if (!willwork)
                        return null;
                    return new VisualBitmapImage(1.0, 1.0, 300, System.Drawing.Color.Black);
                });
            }

            public DeepZoomPivotConstructor.VisualLib.Visual Render(object what, System.Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool requestComposableUnit = false)
            {
                throw new System.NotImplementedException();
            }
        }

        /// <summary>
        /// Do MEF so we are ready to test this thing.
        /// </summary>
        /// <param name="target"></param>
        private void PreparePlugin(StringWildCardToInfoRender target, bool addLocalPath = true, string filedirmatcher = ".*", string postRenderMatch = ".*")
        {
            if (addLocalPath)
            {
                var dude = new testme() { localLocation = new DirectoryInfo(".") };
                t_TestingLibrary.Utilities.AddPart(dude);
            }

            t_TestingLibrary.Utilities.AddPart(new DummyRender(renderWildcard: filedirmatcher, postRenderMatch: postRenderMatch));
            t_TestingLibrary.Utilities.AddPart(new LayoutHelper());
            t_TestingLibrary.Utilities.Compose(target);
        }

        /// <summary>
        /// Create a file to help with testing.
        /// </summary>
        /// <param name="fname"></param>
        /// <returns></returns>
        private FileInfo CreateFile(string fname, DirectoryInfo baseDir = null)
        {
            var bd = new DirectoryInfo(".");
            if (baseDir != null)
                bd = baseDir;

            var f = new FileInfo(string.Format(@"{0}\{1}", bd.FullName, fname));
            if (f.Exists)
                f.Delete();

            using (var output = f.CreateText())
            {
                output.WriteLine("hi");
                output.Close();
            }

            f.Refresh();
            return f;
        }
    }
}
